
package com.quirqy.servlet;


import java.io.IOException;
import java.util.List;
import java.util.ArrayList;


import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.persistence.EntityManager; 

//jackson for JSON support ? necessary?

import org.codehaus.jackson.map.ObjectMapper;

import com.quirqy.model.Person;
import com.quirqy.persistence.EMF;

public class PersonServlet extends HttpServlet {
  
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws IOException {
      
	EntityManager em = EMF.get().createEntityManager();
        
	List<Person> users = new ArrayList<Person>();;
	try
	{             
		String path = req.getPathInfo();
		
		//Does the path contain an Id for single object lookup?
        if (
        	(path !=null) &&
        	(path.matches("/\\d+"))
        	)
        {
        	String sId = path.substring(path.lastIndexOf('/')+1);
            Person pOrig = em.find(Person.class, Long.parseLong(sId));
             
            users.add(pOrig);
        }
        //The path is assumed to be looking for all items
        else 
        {
            javax.persistence.Query query = em.createQuery("select p from Person p ");
            users = (List<Person>)query.getResultList();
        }
	} finally {
		em.close();
	}
		ObjectMapper mapper = new ObjectMapper();
		resp.setContentType("text/plain");
		mapper.writeValue(resp.getWriter(), users);
	}
  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException {
      
      //accept the request body as json, and use
      // jackson library to produce a Person object.
      // add that person object to DB, and if successful,
      // return 201.
	int iResponseCode = resp.SC_INTERNAL_SERVER_ERROR;
	ObjectMapper mapper = new ObjectMapper();
	Person p = mapper.readValue(req.getReader(), Person.class);

	EntityManager em = EMF.get().createEntityManager();
	
	try
	{
		em.getTransaction().begin();
	    Person pOrig = em.find(Person.class, p.getId());
	    //nasty code. Must be genericised, and rules-based. For example, don't update same or null values.
	    //would have thought merge gave me this for free....
	    if (pOrig==null)
	    {
		    em.persist(p);
    	    em.flush();
    	    iResponseCode = resp.SC_CREATED;
	    }
	    else
	    {
	    	//the guy is trying to edit a person that doesn't exist...can you believe that?
	    	iResponseCode = resp.SC_NOT_ACCEPTABLE;
	    }
	    em.getTransaction().commit();
	}
	finally
	{
	    em.close();
	}

	resp.setStatus(iResponseCode);
  }
  @Override
  public void doPut(HttpServletRequest req, HttpServletResponse resp)
      throws IOException {

    int iResponseCode = resp.SC_INTERNAL_SERVER_ERROR;
    ObjectMapper mapper = new ObjectMapper();
	Person p = mapper.readValue(req.getReader(), Person.class);

	EntityManager em = EMF.get().createEntityManager();

	try
	{
		em.getTransaction().begin();
	    Person pOrig = em.find(Person.class, p.getId());
	    if (pOrig==null)
	    {
	    	//the guy is trying to add a new person, can you believe that?
			iResponseCode = resp.SC_NOT_ACCEPTABLE ;
	    }
	    else
	    {
			//nasty code. Must be genericised, and rules-based. For example, don't update same or null values.
			//would have thought merge gave me this for free....
			pOrig.setEmail(p.getEmail());
			pOrig.setName(p.getName());
			pOrig.setPassword(p.getPassword());
			
			em.merge(pOrig); 
			iResponseCode = resp.SC_OK;
		}
		em.getTransaction().commit();
		
	}
	finally
	{
	    em.close();
	}

	resp.setStatus(iResponseCode);
  }
  @Override
  public void doDelete(HttpServletRequest req, HttpServletResponse resp)
      throws IOException {
      
    int iResponseCode = resp.SC_INTERNAL_SERVER_ERROR;
    ObjectMapper mapper = new ObjectMapper();
	Person p = mapper.readValue(req.getReader(), Person.class);

	EntityManager em = EMF.get().createEntityManager();
	
	try
	{
		em.getTransaction().begin();
	    Person pOrig = em.find(Person.class, p.getId());
		em.remove(pOrig); 
		em.getTransaction().commit();
		iResponseCode = resp.SC_OK;
	}
	finally
	{
	    em.close();
	}
	
	resp.setStatus(iResponseCode);
	}
}
